// package gftenant
// @Author Larry<jclarry@qq.com>
// @CreatedAt 2024/4/23 14:39
// @Desc

package gftenant

import (
	"context"
	"fmt"
	"strings"

	"github.com/gogf/gf/v2/database/gdb"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/os/gctx"
	"github.com/gogf/gf/v2/util/gconv"
)

var dbSwitch Handle

func DBHandle(i Handle) {
	dbSwitch = i
}

type Handle func(tenantId string) (Model, error)

var config *Config

type Config struct {
	Mode       string `json:"mode" dc:"none"`            //none 不启用  column 列模式  db 数据库模式
	ColumnName string `json:"columnName" dc:"tenant_id"` //column模式的列名 默认 tenant_id
	//IgnoreTable []string `json:"ignoreTable"`    //忽略的表 只对column模式生效
}

func init() {
	config = &Config{
		Mode: ModeNone,
	}
	v := g.Cfg().MustGet(gctx.GetInitCtx(), "tenant")
	if !v.IsEmpty() {
		if err := v.Scan(&config); err != nil {
			panic(err)
		}
	}
}

func GetColumnName() string {
	if config.ColumnName == "" {
		return "tenant_id"
	}
	return strings.ToLower(config.ColumnName)
}

// GetTenant 获取当前上下文贴牌ID
func GetTenant(ctx context.Context) string {
	return strings.ToLower(gconv.String(ctx.Value(GetColumnName())))
}

// SetTenant 设置当前上下文贴牌ID
func SetTenant(ctx context.Context, id string) context.Context {
	return context.WithValue(ctx, GetColumnName(), strings.ToLower(id))
}
func Init(ctx context.Context) gdb.DB {
	if strings.ToLower(config.Mode) != ModeDB {
		return nil
	}
	id := GetTenant(ctx)
	m, err := dbSwitch(id)
	if err != nil {
		panic(err)
	}
	if ll := gdb.GetConfig(id); len(ll) == 0 {
		gdb.SetConfigGroup(id, gdb.ConfigGroup{
			gdb.ConfigNode{
				Debug: false,
				Link:  fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", m.DbAccount, m.DbPass, m.DbAddr, m.DbPort, m.DbName),
				Type:  "mysql",
			},
		})
	}
	db := g.DB(id)
	err = db.PingMaster()
	if err != nil {
		panic(err)
	}
	return db
}
